package cn.lijiajia3515.cairo.auth.modules.serial;

import cn.lijiajia3515.cairo.core.CoreConstants;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;


@Service
public class SerialService {
	private final MongoTemplate mongoTemplate;

	public SerialService(MongoTemplate mongoTemplate) {
		this.mongoTemplate = mongoTemplate;
	}

	long next(String client, String id) {
		Criteria criteria = Criteria.where(SerialMongo.FIELD.CLIENT).is(client).and(SerialMongo.FIELD.ID).is(id);
		Query query = Query.query(criteria);
		query.fields().include(SerialMongo.FIELD.VALUE);

		Update update = new Update();
		update.inc(SerialMongo.FIELD.VALUE);

		FindAndModifyOptions options = FindAndModifyOptions.options().upsert(true);

		return mongoTemplate.update(SerialMongo.class)
			.inCollection(SerialConstants.MONGO_COLLECTION)
			.matching(criteria)
			.apply(update)
			.withOptions(options)
			.findAndModify()
			.map(SerialMongo::getValue)
			.orElse(CoreConstants.SNOWFLAKE.nextId());
	}

	void create(String client, String key, long initValue, String name) {
		SerialMongo.builder()
			.client(client)
			.id(key)
			.name(name)
			.value(initValue)
			.build();
		mongoTemplate.insert(SerialMongo.class, SerialConstants.MONGO_COLLECTION);
	}
}
